import cookieParser from 'cookie-parser';
import morgan from 'morgan';
import path from 'path';
import helmet from 'helmet';
import express, { Request, Response, NextFunction } from 'express';
import logger from 'jet-logger';
import cors from 'cors';

import 'express-async-errors';
import Paths from '@src/common/Paths';
import HttpStatusCodes from '@src/common/HttpStatusCodes';
import { RouteError } from '@src/common/classes';
import { NodeEnvs } from '@src/common/misc';

import SwaggerSpec from './util/swagger';
import swaggerUi from 'swagger-ui-express';
import { verifyToken } from './util/jwt';

// **** Import routes **** //
import AuthRouter from '@src/routes/AuthRouter'
import PublicRouter from '@src/routes/PublicRouter'
import UserRouter from '@src/routes/UserRouter'
import FriendRouter from '@src/routes/FriendRouter'


// **** Variables **** //

const app = express();

// **** Setup **** //

app.use(cors());

app.use(express.static(path.join(process.cwd(), 'public'))); // 静态资源

// 将 Swagger UI 集成到 Express 应用中
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(SwaggerSpec));
// Basic middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());

// Show routes called in console during development
if (process.env.NodeEnv === NodeEnvs.Dev.valueOf()) {
  app.use(morgan('dev'));
}

// Security
if (process.env.NodeEnv === NodeEnvs.Production.valueOf()) {
  app.use(helmet());
}

// Add APIs, must be after middleware
app.use(Paths.Auth.Base, AuthRouter);
app.use(Paths.Apis.Base, PublicRouter);
app.use(Paths.Users.Base, verifyToken ,UserRouter);
app.use(Paths.Friend.Base, verifyToken ,FriendRouter);

// Add error handler
app.use((err: any, _: Request, res: Response, next: NextFunction) => {
  console.log('全局处理', err);
  if (process.env.NODE_ENV !== NodeEnvs.Test.valueOf()) {
    logger.err(err, true);
  }

  let status = HttpStatusCodes.BAD_REQUEST;
  if (err instanceof RouteError) {
    status = err.status;
    res.status(status).json({ error: err.message });
  }

  // 返回标准错误响应
  res.status(err.code || HttpStatusCodes.INTERNAL_SERVER_ERROR).json({
    code: err.code || HttpStatusCodes.INTERNAL_SERVER_ERROR,
    success: err.success || false,
    message: err.message || 'Internal Server Error',
    data: err.data || null,
  });
});


// **** Export default **** //

export default app;
